package com.gitee.dolt.boot.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ReflectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.gitee.dolt.boot.mapper.SuperMapper;
import com.gitee.dolt.core.exception.BizException;
import com.gitee.dolt.core.exception.code.ExceptionCode;

import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;


/**
 * @author LYH
 */
public class SuperServiceImpl<M extends SuperMapper<T>, T> extends ServiceImpl<M, T> implements SuperService<T> {

    public SuperMapper getSuperMapper() {
        if (baseMapper instanceof SuperMapper) {
            return baseMapper;
        }
        throw new BizException(ExceptionCode.INTERNAL_SERVER_ERROR);
    }


    @Override
    public boolean updateAllById(T entity) {
        return SqlHelper.retBool(getSuperMapper().updateAllById(entity));
    }


    @Override
    public Object handlerByPage(long size, Consumer<QueryWrapper<T>> fillQuery, BiConsumer<Object, List<T>> dataHandler) {
        TableInfo tableInfo = TableInfoHelper.getTableInfo(currentModelClass());
        String keyColumn = tableInfo.getKeyColumn();
        String keyProperty = tableInfo.getKeyProperty();
        return this.handlerByPage(size, fillQuery, keyColumn, keyProperty, dataHandler);
    }

    @Override
    public Object handlerByPage(long size, Consumer<QueryWrapper<T>> fillQuery,
                                String fieldColumn, String fieldProperty, BiConsumer<Object, List<T>> dataHandler) {
        Object lastValue = null;
        Page<T> page = new Page<T>().setSize(size).setSearchCount(false);
        QueryWrapper<T> qw = Wrappers.<T>query().orderByAsc(fieldColumn);
        fillQuery.accept(qw);

        Page<T> dataPage = super.page(page, qw);
        List<T> records = dataPage.getRecords();
        // 超过条数会被PaginationInterceptor处理
        size = page.getSize();

        while (CollUtil.isNotEmpty(records)) {
            T last = CollUtil.getLast(records);
            lastValue = ReflectUtil.getFieldValue(last, fieldProperty);
            // 先提取大小,避免处理时改变了record的大小
            int recordSize = records.size();
            dataHandler.accept(lastValue, records);
            if (recordSize != size) {
                break;
            }
            qw = Wrappers.<T>query().orderByAsc(fieldColumn).gt(fieldColumn, lastValue);
            fillQuery.accept(qw);
            dataPage = super.page(page, qw);
            records = dataPage.getRecords();
        }
        return lastValue;
    }
}
